using System;
using System.Drawing;
using Wilco.SyntaxHighlighting.Engine.Highlighter;
using Wilco.SyntaxHighlighting.Engine.Node.Implementation.Word;
using Wilco.SyntaxHighlighting.Engine.Parser;
using Wilco.SyntaxHighlighting.Engine.Scanner;
using Wilco.SyntaxHighlighting.Engine.Scanner.Implementation;

namespace Wilco.SyntaxHighlighting.Engine.Highlighter.Implementation
{
    /// <summary>
    /// Represents a COBOL syntax highlighter.
    /// </summary>
    public class CobolHighlighter : HighlighterBase
    {
        /// <summary>
        /// Initializes a new instance of a <see cref="CobolHighlighter"/> class.
        /// </summary>
        public CobolHighlighter() : this(null)
        {
        }

        /// <summary>
        /// Initializes a new instance of a <see cref="CobolHighlighter"/> class.
        /// </summary>
        /// <param name="parser">The parser which will be used to parse the source code.</param>
        public CobolHighlighter(IParser parser) : base(parser)
        {
            Name = "COBOL";
            FullName = "COBOL";
            TagValues.AddRange(new String[] { "cob" });
            FileExtensions.Add("cob");
        }

        /// <summary>
        /// Creates a new instance (clone) of this highlighter.
        /// </summary>
        /// <returns></returns>
        public override HighlighterBase Create()
        {
            return new CobolHighlighter(Parser);
        }

        /// <summary>
        /// Builds a word scanner.
        /// </summary>
        /// <returns>A <see cref="WordScanner"/> object.</returns>
        protected override IScanner BuildWordScanner()
        {
            WordScanner scanner = new WordScanner(Tokenizer, ScannerResult);
            scanner.WordNodes = new WordNode[1];
            scanner.WordNodes[0] = new WordNode();
            scanner.WordNodes[0].ForeColor = Color.Blue;
            scanner.WordNodes[0].Entities.AddRange(GetKeywords());
            return scanner;
        }

        /// <summary>
        /// Gets an array of registered keywords.
        /// </summary>
        /// <returns>An array of keywords.</returns>
        private static string[] GetKeywords()
        {
            string[] keywordList = new string[]
                {
                    "ACCEPT",
                    "ACCESS",
                    "ACTUAL",
                    "ADD",
                    "ADDRESS",
                    "ADVANCING",
                    "AFTER",
                    "ALL",
                    "ALPHABET",
                    "ALPHABETIC",
                    "ALPHABETIC-LOWER",
                    "ALPHABETIC-UPPER",
                    "ALPHANUMERIC",
                    "ALPHANUMERIC-EDITED",
                    "ALS",
                    "ALTER",
                    "ALTERNATE",
                    "AND",
                    "ANY",
                    "APPLY",
                    "ARE",
                    "AREA",
                    "AREAS",
                    "ARITHMETIC",
                    "AS",
                    "ASCENDING",
                    "ASSIGN",
                    "AT",
                    "AUTHOR",
                    "AUTO",
                    "AUTOMATIC",
                    "B-AND",
                    "B-EXOR",
                    "B-LESS",
                    "B-NOT",
                    "B-OR",
                    "BASED",
                    "BACKGROUND-COLOR",
                    "BASED-STORAGE",
                    "BEFORE",
                    "BEGINNING",
                    "BELL",
                    "BINARY",
                    "BIT",
                    "BITS",
                    "BLANK",
                    "BLINK",
                    "BLOCK",
                    "BOOLEAN",
                    "BOTTOM",
                    "BY",
                    "CALL",
                    "CANCEL",
                    "CBL",
                    "CD",
                    "CF",
                    "CH",
                    "CHANGED",
                    "CHARACTER",
                    "CHARACTERS",
                    "CLASS",
                    "CLASS-ID",
                    "CLOCK-UNITS",
                    "CLOSE",
                    "COBOL",
                    "CODE",
                    "CODE-SET",
                    "COLLATING",
                    "COLUMN",
                    "COMMA",
                    "COMMAND",
                    "COMMIT",
                    "COMMON",
                    "COMMUNICATION",
                    "COM-REG",
                    "COMP",
                    "COMP-1",
                    "COMP-2",
                    "COMP-3",
                    "COMP-4",
                    "COMP-5",
                    "COMP-n",
                    "COMPLEX",
                    "COMPUTATIONAL",
                    "COMPUTATIONAL-1",
                    "COMPUTATIONAL-2",
                    "COMPUTATIONAL-3",
                    "COMPUTATIONAL-4",
                    "COMPUTATIONAL-5",
                    "COMPUTATIONAL-n",
                    "COMPUTE",
                    "CONFIGURATION",
                    "CONNECT",
                    "CONSTANT",
                    "CONTAINED",
                    "CONTAINS",
                    "CONTENT",
                    "CONTINUE",
                    "CONTROL",
                    "CONTROL-CHARACTER",
                    "CONTROLS",
                    "CONVERTING",
                    "COPY",
                    "CORE-INDEX",
                    "CORR",
                    "CORRESPONDING",
                    "COUNT",
                    "CRP",
                    "CRT",
                    "CRT-UNDER",
                    "CURRENCY",
                    "CURRENT",
                    "CURSOR",
                    "DATA",
                    "DATE",
                    "DATE-COMPILED",
                    "DATE-WRITTEN",
                    "DAY",
                    "DAY-OF-WEEK",
                    "DB",
                    "DB-ACCESS-CONTROL-KEY",
                    "DB-DATA-NAME",
                    "DB-EXCEPTION",
                    "DB-RECORD-NAME",
                    "DB-SET-NAME",
                    "DB-STATUS",
                    "DE",
                    "DEAD-LOCK",
                    "DEBUG-CONTENTS",
                    "DEBUG-ITEM",
                    "DEBUG-LINE",
                    "DEBUG-NAME",
                    "DEBUG-SUB-1",
                    "DEBUG-SUB-2",
                    "DEBUG-SUB-3",
                    "DEBUGGING",
                    "DECIMAL-POINT",
                    "DECLARATIVES",
                    "DEFAULT",
                    "DELETE",
                    "DELIMITED",
                    "DELIMITER",
                    "DEPENDING",
                    "DESCENDING",
                    "DESTINATION",
                    "DESTINATION-1",
                    "DESTINATION-2",
                    "DESTINATION-3",
                    "DETAIL",
                    "DEVICE",
                    "DIRECT",
                    "DISABLE",
                    "DISCONNECT",
                    "DISJOINING",
                    "DISPLAY",
                    "DISPLAY-1",
                    "DISPLAY-EXIT",
                    "DISPLAY-n",
                    "DIVIDE",
                    "DIVISION",
                    "DOWN",
                    "DUPLICATE",
                    "DUPLICATES",
                    "DYNAMIC",
                    "EDIT-COLOR",
                    "EDIT-CURSOR",
                    "EDIT-MODE",
                    "EDIT-OPTION",
                    "EDIT-STATUS",
                    "EGCS",
                    "EGI",
                    "EJECT",
                    "ELSE",
                    "EMI",
                    "EMPTY",
                    "ENABLE",
                    "END",
                    "END-ACCEPT",
                    "END-ADD",
                    "END-CALL",
                    "END-COMPUTE",
                    "END-DELETE",
                    "END-DISABLE",
                    "END-DISPLAY",
                    "END-DIVIDE",
                    "END-ENABLE",
                    "END-EVALUATE",
                    "END-EXEC",
                    "END-IF",
                    "END-INVOKE",
                    "END-MULTIPLY",
                    "END-OF-PAGE",
                    "END-PERFORM",
                    "END-READ",
                    "END-RECEIVE",
                    "END-RETURN",
                    "END-REWRITE",
                    "END-SEARCH",
                    "END-SEND",
                    "END-START",
                    "END-STRING",
                    "END-SUBTRACT",
                    "END-TRANSCEIVE",
                    "END-UNSTRING",
                    "END-WRITE",
                    "ENDCOBOL",
                    "ENDING",
                    "ENTER",
                    "ENTRY",
                    "ENVIRONMENT",
                    "EOL",
                    "EOP",
                    "EOS",
                    "EQUAL",
                    "EQUALS",
                    "ERASE",
                    "ERROR",
                    "ESI",
                    "EVALUATE",
                    "EVERY",
                    "EXACT",
                    "EXAMINE",
                    "EXCEEDS",
                    "EXCEPTION",
                    "EXCEPTION-OBJECT",
                    "EXCLUSIVE",
                    "EXEC",
                    "EXIT",
                    "EXOR",
                    "EXTEND",
                    "EXTERNAL",
                    "FACTORY",
                    "FALSE",
                    "FD",
                    "FETCH",
                    "FILE",
                    "FILE-CONTROL",
                    "FILE-LIMIT",
                    "FILE-LIMITS",
                    "FILES",
                    "FILLER",
                    "FINAL",
                    "FIND",
                    "FINISH",
                    "FIRST",
                    "FLADD",
                    "FOOTING",
                    "FOR",
                    "FOREGROUND-COLOR",
                    "FORM",
                    "FORMAT",
                    "FORMATTED",
                    "FREE",
                    "FROM",
                    "FULL",
                    "FUNCTION",
                    "GENERATE",
                    "GET",
                    "GIVING",
                    "GLOBAL",
                    "G",
                    "GOBACK",
                    "GREATER",
                    "GRID",
                    "GROUP",
                    "HEADING",
                    "HIGHLIGHT",
                    "HIGH-VALUE",
                    "HIGH-VALUES",
                    "I-",
                    "I-O-CONTROL",
                    "ID",
                    "IDENTIFICATION",
                    "IF",
                    "IN",
                    "INCLUDE",
                    "INDEX",
                    "INDEX-n",
                    "INDEXED",
                    "INDICATE",
                    "INHERITS",
                    "INITIAL",
                    "INITIALIZE",
                    "INITIATE",
                    "INPUT",
                    "INPUT-OUTPUT",
                    "INSPECT",
                    "INSTALLATION",
                    "INT",
                    "INVALID",
                    "INVARIANT",
                    "INVOKE",
                    "IS",
                    "JAPANESE",
                    "JOB",
                    "JOINING",
                    "JUST",
                    "JUSTIFIED",
                    "KANJI",
                    "KEEP",
                    "KEY",
                    "LABEL",
                    "LAST",
                    "LD",
                    "LEADING",
                    "LEFT",
                    "LEFTLINE",
                    "LEFT-JUSTIFY",
                    "LENGTH",
                    "LESS",
                    "LIMIT",
                    "LIMITED",
                    "LIMITS",
                    "LINAGE",
                    "LINAGE-COUNTER",
                    "LINE",
                    "LINE-COUNTER",
                    "LINES",
                    "LINKAGE",
                    "LOCALLY",
                    "LOCK",
                    "LOW-VALUE",
                    "LOW-VALUES",
                    "LOWLIGHT",
                    "MANUAL",
                    "MEMBER",
                    "MEMORY",
                    "MERGE",
                    "MESSAGE",
                    "METHOD",
                    "METHOD-ID",
                    "MODE",
                    "MODE-1",
                    "MODE-2",
                    "MODE-3",
                    "MODIFY",
                    "MODULES",
                    "MORE-LABELS",
                    "MOVE",
                    "MULTICON",
                    "MULTICONVERSATIONMODE",
                    "MULTIPLE",
                    "MULTIPLY",
                    "NAMED",
                    "NATIONAL",
                    "NATIONAL-EDITED",
                    "NATIVE",
                    "NEGATIVE",
                    "NEXT",
                    "NO",
                    "NOMINAL",
                    "NONE",
                    "NOT",
                    "NOTE",
                    "NULL",
                    "NULLS",
                    "NUMBER",
                    "NUMERIC",
                    "NUMERIC-EDITED",
                    "OBJECT",
                    "OBJECT-COMPUTER",
                    "OCCURS",
                    "OF",
                    "OFF",
                    "OMITTED",
                    "ON",
                    "ONLY",
                    "OPEN",
                    "OPTIONAL",
                    "OR",
                    "ORDER",
                    "ORGANIZATION",
                    "OTHER",
                    "OTHERWISE",
                    "OUTPUT",
                    "OVERFLOW",
                    "OVERLINE",
                    "OVERRIDE",
                    "OWNER",
                    "PACKED-DECIMAL",
                    "PADDING",
                    "PAGE",
                    "PAGE-COUNTER",
                    "PARAGRAPH",
                    "PASSWORD",
                    "PERFORM",
                    "PF",
                    "PH",
                    "PIC",
                    "PICTURE",
                    "PLUS",
                    "POINTER",
                    "POSITION",
                    "POSITIONING",
                    "POSITIVE",
                    "PREFIX",
                    "PRESENT",
                    "PREVIOUS",
                    "PRINTING",
                    "PRIOR",
                    "PROCEDURE",
                    "PROCEDURES",
                    "PROCEED",
                    "PROCESSING",
                    "PROGRAM",
                    "PROGRAM-ID",
                    "PROGRAM-STATUS",
                    "PROMPT",
                    "PROPERTY",
                    "PROTECTED",
                    "PROTOPTYPE",
                    "PURGE",
                    "QUEUE",
                    "QUOTE",
                    "QUOTES",
                    "RAISE",
                    "RAISING",
                    "RANDOM",
                    "RANGE",
                    "RD",
                    "READ",
                    "READY",
                    "REALM",
                    "RECEIVE",
                    "RECONNECT",
                    "RECORD",
                    "RECORD-NAME",
                    "RECORD-OVERFLOW",
                    "RECORDING",
                    "RECORDS",
                    "REDEFINES",
                    "REEL",
                    "REFERENCE",
                    "REFERENCES",
                    "RELATION",
                    "RELATIVE",
                    "RELEASE",
                    "RELOAD",
                    "REMAINDER",
                    "REMARKS",
                    "REMOVAL",
                    "RENAMES",
                    "REORG-CRITERIA",
                    "REPEATED",
                    "REPLACE",
                    "REPLACING",
                    "REPORT",
                    "REPORTING",
                    "REPORTS",
                    "REPOSITORY",
                    "RERUN",
                    "REQUIRED",
                    "RESERVE",
                    "RESET",
                    "RETAINING",
                    "RETRIEVAL",
                    "RETURN",
                    "RETURNING",
                    "RETURN-CODE",
                    "REVERSE-VIDEO",
                    "REVERSED",
                    "REWIND",
                    "REWRITE",
                    "RF",
                    "RH",
                    "RIGHT",
                    "RIGHT-JUSTIFY",
                    "ROLL-OUT",
                    "ROLLBACK",
                    "ROUNDED",
                    "RUN",
                    "SA",
                    "SAME",
                    "SAVED-AREA",
                    "SCREEN",
                    "SD",
                    "SEARCH",
                    "SECTION",
                    "SECURITY",
                    "SECURE",
                    "SEEK",
                    "SELF",
                    "SEGMENT",
                    "SEGMENT-LIMIT",
                    "SELECT",
                    "SELECTED",
                    "SELECTIVE",
                    "SEND",
                    "SENTENCE",
                    "SEPARATE",
                    "SEQUENCE",
                    "SEQUENTIAL",
                    "SERVICE",
                    "SESSION",
                    "SESSION-ID",
                    "SET",
                    "SHARED",
                    "SHIFT-IN",
                    "SHIFT-OUT",
                    "SIGN",
                    "SIMPLE",
                    "SINGLE",
                    "SIZE",
                    "SKIP1",
                    "SKIP2",
                    "SKIP3",
                    "SORT",
                    "SORT-CONTROL",
                    "SORT-CORE-SIZE",
                    "SORT-FILE-SIZE",
                    "SORT-MESSAGE",
                    "SORT-MERGE",
                    "SORT-MODE-SIZE",
                    "SORT-RETURN",
                    "SORT-STATUS",
                    "SOURCE",
                    "SOURCE-COMPUTER",
                    "SPACE",
                    "SPACE-FILL",
                    "SPACES",
                    "SPECIAL-NAMES",
                    "STANDARD",
                    "STANDARD-1",
                    "STANDARD-2",
                    "START",
                    "STATION",
                    "STATIONS",
                    "STATUS",
                    "STOP",
                    "STORE",
                    "STRING",
                    "SUB-QUEUE-1",
                    "SUB-QUEUE-2",
                    "SUB-QUEUE-3",
                    "SUBRANGE",
                    "SUB-SCHEMA",
                    "SUBSCHEMA-NAME",
                    "SUBTRACT",
                    "SUCCESSIVE",
                    "SUFFIX",
                    "SUM",
                    "SUPER",
                    "SUPPRESS",
                    "SYMBOLIC",
                    "SYNC",
                    "SYNCHRONIZED",
                    "TABLE",
                    "TALLY",
                    "TALLYING",
                    "TAPE",
                    "TENANT",
                    "TENNANT",
                    "TERMINAL",
                    "TERMINATE",
                    "TEST",
                    "TEXT",
                    "THAN",
                    "THEN",
                    "THROUGH",
                    "THRU",
                    "TIME",
                    "TIMEOUT",
                    "TIMES",
                    "TITLE",
                    "TO",
                    "TOP",
                    "TRACE",
                    "TRACK",
                    "TRACK-AREA",
                    "TRACK-LIMIT",
                    "TRACK-OVERFLOW",
                    "TRACKS",
                    "TRAILING",
                    "TRAILING-SIGN",
                    "TRANSACTION",
                    "TRANSCEIVE",
                    "TRUE",
                    "TYPE",
                    "TYPEDEF",
                    "UNDERLINE",
                    "UNEQUAL",
                    "UNIT",
                    "UNIVERSAL",
                    "UNLOCK",
                    "UNSTRING",
                    "UNTIL",
                    "UP",
                    "UPDATE",
                    "UPON",
                    "USAGE",
                    "USAGE-MODE",
                    "USE",
                    "USING",
                    "VALID",
                    "VALIDATE",
                    "VALUE",
                    "VALUES",
                    "VARYING",
                    "WAIT",
                    "WHEN",
                    "WHEN-COMPILED",
                    "WITH",
                    "WITHIN",
                    "WORDS",
                    "WORKING-STORAGE",
                    "WRITE",
                    "WRITE-ONLY",
                    "ZER",
                    "ZERO-FILL",
                    "ZEROES",
                    "ZEROS"
                };

            Array.Sort(keywordList);
            Array.Reverse(keywordList);

            return keywordList;
        }
    }
}